package com.jiedeng.util.httpclient;


import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;

public abstract class SSLUtils {

  private static Logger logger = LoggerFactory.getLogger(SSLUtils.class);

  private SSLUtils() {
  }

  public static CloseableHttpClient createSSLInsecureClient() {
    try {
      SSLContext sslcontext = custom("tomcat.keystore", "123456");
//      sslcontext = createIgnoreVerifySSL();
      // 设置协议http和https对应的处理socket链接工厂的对象
      Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
          .register("http", PlainConnectionSocketFactory.INSTANCE)
          .register("https", new SSLConnectionSocketFactory(sslcontext))
          .build();
      PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(
          socketFactoryRegistry);
      //创建自定义的httpclient对象
      return HttpClients.custom().setConnectionManager(connManager).build();
    } catch (Exception e) {
      logger.error("createSSLInsecureClient error:" + e.getMessage(), e);
    }
    return HttpClients.createDefault();
  }

  /**
   * 设置信任自签名证书
   *
   * @param keyStorePath 密钥库路径
   * @param keyStorepass 密钥库密码
   */
  public static SSLContext custom(String keyStorePath, String keyStorepass) {
    SSLContext sc = null;
    InputStream inputStream = null;
    KeyStore trustStore;
    try {
      trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
      inputStream = new ClassPathResource(keyStorePath).getInputStream();
      trustStore.load(inputStream, keyStorepass.toCharArray());
      // 相信自己的CA和所有自签名的证书
      sc = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy())
          .build();
    } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException | KeyManagementException e) {
      logger.error("SSLContext custom error:" + e.getMessage(), e);
    } finally {
      if (inputStream != null) {
        try {
          inputStream.close();
        } catch (IOException e) {
          logger.error("SSLContext custom IOException:" + e.getMessage(), e);
        }
      }
    }
    return sc;
  }

  /**
   * 绕过验证
   */
  public static SSLContext createIgnoreVerifySSL()
      throws NoSuchAlgorithmException, KeyManagementException {
    SSLContext sc = SSLContext.getInstance("SSLv3");

    // 实现一个X509TrustManager接口，用于绕过验证，不用修改里面的方法
    X509TrustManager trustManager = new X509TrustManager() {
      @Override
      public void checkClientTrusted(
          java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
          String paramString) {
      }

      @Override
      public void checkServerTrusted(
          java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
          String paramString) {
      }

      @Override
      public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return null;
      }
    };

    sc.init(null, new TrustManager[]{trustManager}, null);
    return sc;
  }

}